package com.xoa.service.WFE.WFERunner;

import com.alibaba.fastjson.JSONArray;
import com.xoa.controller.work.WorkController;
import com.xoa.dao.WFE.WFEFlowRunMapper;
import com.xoa.dao.WFE.WFEFlowRunPrcsMapper;
import com.xoa.dao.common.SysParaMapper;
import com.xoa.dao.flowRunFeedback.FlowRunFeedbackMapper;
import com.xoa.dao.sms.SmsBodyMapper;
import com.xoa.dao.work.WorkMapper;
import com.xoa.dao.workflow.*;
import com.xoa.model.common.SysPara;
import com.xoa.model.department.Department;
import com.xoa.model.document.DocumentModel;
import com.xoa.model.document.DocumentModelWithBLOBs;
import com.xoa.model.enclosure.Attachment;
import com.xoa.model.users.Users;
import com.xoa.model.workflow.*;
import com.xoa.service.WFE.WFE;
import com.xoa.service.WFE.WFEFactory.WFEFlowProcess;
import com.xoa.service.WFE.WFELog.WFELog;
import com.xoa.service.document.DocumentSerivce;
import com.xoa.util.*;
import com.xoa.util.aes.AESUtil;
import com.xoa.util.common.L;
import com.xoa.util.common.StringUtils;
import com.xoa.util.common.log.FileUtils;
import com.xoa.util.common.session.SessionUtils;
import com.xoa.util.page.PageParams;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

//流程实例步骤信息类
@SuppressWarnings("all")
@Service
public class WFEFlowRunPrcs extends WFE {

    @Autowired
    private FlowRunPrcsMapper flowRunPrcsMapper;

    @Autowired
    private WFELog wfeLog;

    @Autowired
    protected WFEFlowRunPrcsMapper wfeFlowRunPrcsMapper;

    @Autowired
    protected FlowTypeModelMapper flowTypeModelMapper;

    @Autowired
    protected FlowProcessMapper flowProcessMapper;

    @Autowired
    protected WFEFlowProcess wfeFlowProcess;

    @Autowired
    protected WFEFlowRunMapper wfeFlowRunMapper;

    @Autowired
    protected WorkMapper workMapper;

    @Autowired
    protected SmsBodyMapper smsBodyMapper;

    @Autowired
    protected ToBeReadMapper toBeReadMapper;

    @Autowired
    protected WFEFlowRun wfeFlowRun;

    @Autowired
    protected DocumentSerivce documentSerivce;

    @Autowired
    protected FlowRunFeedbackMapper flowRunFeedbackMapper;

    @Autowired
    protected FlowRunLogMapper flowRunLogMapper;
    @Autowired
    protected WorkController workController;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private WFEFlowRunInfo wfeFlowRunInfo;
    @Autowired
    FlowAssignMapper flowAssignMapper;
    @Resource
    private SysParaMapper sysParaMapper;


    //保存一条FlowRunPrcs的数据
    public void save(FlowRunPrcs flowRunPrcs) {
        wfeFlowRunPrcsMapper.insert(flowRunPrcs);
    }

    /**
     * 创建作者:   张龙飞
     * 方法介绍:   根据部分条件查询流程实例步骤信息
     * 参数说明:
     *
     * @return
     */
    public List<FlowRunPrcs> findByRunId(Map<String, Object> maps) {
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectfrp(maps);
        return list;
    }

    public List<FlowRunPrcs> findByRunIdTopFlag(Map<String, Object> maps) {
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.findByRunIdTopFlag(maps);
        return list;
    }

    public List<FlowRunPrcs> findByRunId1(Map<String, Object> maps) {
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectfrp1(maps);
        return list;
    }

    //更新flowRunPrcs根据prcsId和flowPrcs
    @Transactional
    public void update(FlowRunPrcsExcted flowRunPrcs) {
        wfeFlowRunPrcsMapper.updateByPrimaryKeySelective(flowRunPrcs);
    }

    //更新flowRunPrcs根据prcsId和flowPrcs
    @Transactional
    public int updateSql(Map<String, Object> map) {
        int a = wfeFlowRunPrcsMapper.updateSome(map);
        return a;
    }
    //更新flowRunPrcs根据主键Id
    @Transactional
    public int updateFrpById(FlowRunPrcs flowRunPrcs) {
        int a = wfeFlowRunPrcsMapper.updateFrpById(flowRunPrcs);
        return a;
    }
    public int updateParentPrcsFlag(Map<String, Object> map) {
        int a = wfeFlowRunPrcsMapper.updateParentPrcsFlag(map);
        return a;
    }

    //会签更新
    @Transactional
    public int updateHandle(Map<String, Object> map) {
        int a = wfeFlowRunPrcsMapper.updateHandle(map);
        return a;
    }
    //会签状态修改（会更新COMMENT对应值，办公门户使用）
    @Transactional
    public int updateHandleWithComment(Map<String, Object> map) {
        int a = wfeFlowRunPrcsMapper.updateHandleWithComment(map);
        return a;
    }
    /**
     * 会签流程转交
     *
     * @param runId
     * @param prcsId
     * @param flowPrcs
     * @param prcsFlag
     * @param userId
     * @param deliverTime
     * @param prcsTime
     * @return
     */
    @Transactional
    public int updateHandler(Integer runId, Integer prcsId, Integer flowPrcs,
                             String prcsFlag, String userId, String deliverTime, String prcsTime) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("runId", runId);
        map.put("prcsId", prcsId);
        map.put("prcsFlag", prcsFlag);
        map.put("userId", userId);
        map.put("flowPrcs", flowPrcs);
        map.put("prcsTime", prcsTime);
        map.put("deliverTime", deliverTime);
        int count = wfeFlowRunPrcsMapper.updateHandle(map);
        return count;
    }


    //查询指定流程步骤之前的所有流程
    public List<FlowRunPrcs> findlessRunId(Map<String, Object> maps) {
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.findlessRunId(maps);
        return list;
    }

    //查询当前步骤
    public List<FlowRunPrcs> selectFind(Map<String, Object> map) {
        //查询当前
        List<FlowRunPrcs> flowRunPrcs = wfeFlowRunPrcsMapper.selectFind(map);
        return flowRunPrcs;
    }


    //查询当前步骤
    public List<FlowRunPrcs> selectFind(Integer prcsId, Integer runId, Integer flowPrcs, String userId, String branchCount) {

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("prcsId", prcsId);
        map.put("runId", runId);
        map.put("flowPrcs", flowPrcs);
        map.put("userId", userId);
        map.put("branchCount", branchCount);
        //查询当前
        List<FlowRunPrcs> listFrp = wfeFlowRunPrcsMapper.selectFind(map);
        return listFrp;
    }

    /**
     * 创建作者:   张勇
     * 创建日期:   2017/5/24 20:29
     * 方法介绍:   查询待办工作
     * 参数说明:  修整时间计算
     *
     * @return
     */
    public ToJson<FlowRunPrcs> selectObject(Map<String, Object> maps, Integer page,
                                            Integer pageSize, boolean useFlag) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>();
        PageParams pageParams = new PageParams();
        pageParams.setPage(page);
        pageParams.setPageSize(pageSize);
        pageParams.setUseFlag(useFlag);
        maps.put("page", pageParams);
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectObjcet(maps);
        List<FlowRunPrcs> returnList = new ArrayList<FlowRunPrcs>();
        int len = list.size();
        if (len > 0) {
            toJson.setTotleNum(pageParams.getTotal());
            Date newDate = new Date();
            for (FlowRunPrcs flowRunPrcs : list) {
                flowRunPrcs.getFlowRun().setUserName(usersService.getUserNameById(flowRunPrcs.getFlowRun().getBeginUser()));
                flowRunPrcs.setUserName(usersService.getUserNameById(flowRunPrcs.getUserId()));
                flowRunPrcs.setFlowType(flowTypeModelMapper.queryOneObject(flowRunPrcs.getFlowRun().getFlowId()));
                flowRunPrcs.setAvatar(usersService.getUserAvatar(flowRunPrcs.getFlowRun().getBeginUser()));
                //查询流程并设置流程
                FlowProcess flowProcess = flowProcessMapper.findProcess(flowRunPrcs.getFlowRun().getFlowId(), flowRunPrcs.getFlowPrcs());
                if (flowProcess != null) {
                    flowRunPrcs.setFlowProcess(flowProcess);
                }

                if (DateFormat.getTime(flowRunPrcs.getPrcsTime()) != -621701856) {

//				if(!StringUtils.checkNull(flowRunPrcs.getPrcsTime())) {
                    // 工作接收时间
                    flowRunPrcs.setReceive(DateFormat.getStrTime(DateFormat.getTime(flowRunPrcs.getPrcsTime())));
                    // 办理停留时间
                    flowRunPrcs.setHandleTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(newDate))) - DateFormat.getTime(flowRunPrcs.getPrcsTime())));

                } else {
                    flowRunPrcs.setReceive("");
                    flowRunPrcs.setHandleTime("");
                }
                //工作创建时间
                String createTime = flowRunPrcs.getCreateTime();
                //计算时间转换
                if (DateFormat.getTime(flowRunPrcs.getPrcsTime()) != -621701856 && flowRunPrcs.getPrcsId() > 1 ||
                        DateFormat.getTime(flowRunPrcs.getPrcsTime()) == -621701856 && flowRunPrcs.getPrcsId() > 1) {
                    Integer runId = flowRunPrcs.getRunId();
                    Integer prcsId = flowRunPrcs.getPrcsId() - 1;
                    String userId = (String) maps.get("userId");
                    maps.put("prcsId", prcsId);
                    maps.put("runId", runId);
                    maps.put("flowPrcs", flowRunPrcs.getFlowPrcs());
                    // 到达时间
                    flowRunPrcs.setReceiptTime(DateFormat.getStrTime(DateFormat.getTime(createTime)));
                    // 到达停留时间
                    flowRunPrcs.setArriveTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(newDate))) - DateFormat.getTime(flowRunPrcs.getReceiptTime())));
                } else {
                    flowRunPrcs.setReceiptTime(DateFormat.getStrTime(DateFormat.getTime(createTime)));
                    flowRunPrcs.setArriveTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(newDate))) - DateFormat.getTime(createTime)));
                }
                Map<String, Object> m = new HashMap<String, Object>();
                m.put("runId", flowRunPrcs.getRunId());
                FlowRun flowRun = wfeFlowRunMapper.find(m);
                String userName = usersService.getUserNameById(flowRun.getBeginUser());
                flowRunPrcs.setUserName(userName);
                if (flowRunPrcs.getOtherUser() != null && !flowRunPrcs.getOtherUser().trim().equals("")) {
                    String otherUserName = usersService.getUserNameById(flowRunPrcs.getOtherUser());
                    flowRunPrcs.setOtherUserName(otherUserName);
                }
                returnList.add(flowRunPrcs);
            }
            toJson.setFlag(0);
            toJson.setMsg("ok");
            toJson.setObj(returnList);
            toJson.setObj1(returnList.size());//代办的数量
            toJson.setTotleNum(pageParams.getTotal());
        } else {
            toJson.setFlag(0);
            toJson.setMsg("ok");
        }
        return toJson;
    }


    /**
     * 创建作者: 刘建
     * 创建日期: 2020-06-29 15:03
     * 方法介绍: 查询代办工作/公文
     * @param maps
     * @param page
     * @param pageSize
     * @param useFlag
     * @return com.xoa.util.ToJson<com.xoa.model.workflow.FlowRunPrcs>
     */
    public ToJson<FlowRunPrcs> selectWorkDocument(Map<String, Object> maps, Integer page,
                                                  Integer pageSize, boolean useFlag) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>();
        PageParams pageParams = new PageParams();
        pageParams.setPage(page);
        pageParams.setPageSize(pageSize);
        pageParams.setUseFlag(useFlag);
        maps.put("page", pageParams);
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectWorkDocument(maps);
        List<FlowRunPrcs> returnList = new ArrayList<FlowRunPrcs>();
        int len = list.size();
        if (len > 0) {
            toJson.setTotleNum(pageParams.getTotal());
            Date newDate = new Date();
            for (FlowRunPrcs flowRunPrcs : list) {
                flowRunPrcs.getFlowRun().setUserName(usersService.getUserNameById(flowRunPrcs.getFlowRun().getBeginUser()));
                flowRunPrcs.setUserName(usersService.getUserNameById(flowRunPrcs.getUserId()));
                flowRunPrcs.setFlowType(flowTypeModelMapper.queryOneObject(flowRunPrcs.getFlowRun().getFlowId()));
                flowRunPrcs.setAvatar(usersService.getUserAvatar(flowRunPrcs.getFlowRun().getBeginUser()));
                //查询流程并设置流程
                FlowProcess flowProcess = flowProcessMapper.findProcess(flowRunPrcs.getFlowRun().getFlowId(), flowRunPrcs.getFlowPrcs());
                if (flowProcess != null) {
                    flowRunPrcs.setFlowProcess(flowProcess);
                }

                if (DateFormat.getTime(flowRunPrcs.getPrcsTime()) != -621701856) {
//				if(!StringUtils.checkNull(flowRunPrcs.getPrcsTime())) {
                    // 工作接收时间
                    flowRunPrcs.setReceive(DateFormat.getStrTime(DateFormat.getTime(flowRunPrcs.getPrcsTime())));
                    // 办理停留时间
                    flowRunPrcs.setHandleTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(newDate))) - DateFormat.getTime(flowRunPrcs.getPrcsTime())));
                } else {
                    flowRunPrcs.setReceive("");
                    flowRunPrcs.setHandleTime("");
                }
                //工作创建时间
                String createTime = flowRunPrcs.getCreateTime();
                //计算时间转换
                if (DateFormat.getTime(flowRunPrcs.getPrcsTime()) != -621701856 && flowRunPrcs.getPrcsId() > 1 ||
                        DateFormat.getTime(flowRunPrcs.getPrcsTime()) == -621701856 && flowRunPrcs.getPrcsId() > 1) {
                    Integer runId = flowRunPrcs.getRunId();
                    Integer prcsId = flowRunPrcs.getPrcsId() - 1;
                    String userId = (String) maps.get("userId");
                    maps.put("prcsId", prcsId);
                    maps.put("runId", runId);
                    maps.put("flowPrcs", flowRunPrcs.getFlowPrcs());
                    // 到达时间
                    flowRunPrcs.setReceiptTime(DateFormat.getStrTime(DateFormat.getTime(createTime)));
                    // 到达停留时间
                    flowRunPrcs.setArriveTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(newDate))) - DateFormat.getTime(flowRunPrcs.getReceiptTime())));
                } else {
                    flowRunPrcs.setReceiptTime(DateFormat.getStrTime(DateFormat.getTime(createTime)));
                    flowRunPrcs.setArriveTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(newDate))) - DateFormat.getTime(createTime)));
                }
                Map<String, Object> m = new HashMap<String, Object>();
                m.put("runId", flowRunPrcs.getRunId());
                FlowRun flowRun = wfeFlowRunMapper.find(m);
                String userName = usersService.getUserNameById(flowRun.getBeginUser());
                flowRunPrcs.setUserName(userName);
                if (flowRunPrcs.getOtherUser() != null && !flowRunPrcs.getOtherUser().trim().equals("")) {
                    String otherUserName = usersService.getUserNameById(flowRunPrcs.getOtherUser());
                    flowRunPrcs.setOtherUserName(otherUserName);
                }
				//判断是否是公文
                Integer integer = wfeFlowRunPrcsMapper.selectBolDocument(flowRunPrcs.getRunId());
                if(integer != null && integer>0){
                    flowRunPrcs.setDocId(integer);
                }
                returnList.add(flowRunPrcs);
            }
            toJson.setFlag(0);
            toJson.setMsg("ok");
            toJson.setObj(returnList);
        } else {
            toJson.setFlag(0);
            toJson.setMsg("ok");
        }
        return toJson;
    }




    /**
     * 创建作者:
     * 方法介绍:   查询办结工作
     * 参数说明:
     *
     * @return
     */
    public ToJson<FlowRunPrcs> selectEnd(Map<String, Object> maps, Integer page,
                                         Integer pageSize, boolean useFlag) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>(1, "error");
        PageParams pageParams = new PageParams();
        pageParams.setPage(page);
        pageParams.setPageSize(pageSize);
        pageParams.setUseFlag(useFlag);
        maps.put("page", pageParams);
        //按分页取出对应条数的runId
        try {
            List<FlowRunPrcs> mapList = wfeFlowRunPrcsMapper.selEndRunId(maps);
            List<String> listRunId = new ArrayList<String>();
            for (int i = 0; i < mapList.size(); i++) {
                FlowRunPrcs flowRunPrcs = mapList.get(i);
                listRunId.add(flowRunPrcs.getRunId().toString());
            }
            maps.remove("page");
            maps.put("listRunId", listRunId);
            //当前分页
            List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectEnd(maps);
            List<FlowRunPrcs> l = new ArrayList<FlowRunPrcs>();
            Map<Integer, List<FlowRunPrcs>> mAll = new LinkedHashMap<Integer, List<FlowRunPrcs>>();
            FlowRunPrcs temp = new FlowRunPrcs();
            FlowRunPrcs frp = new FlowRunPrcs();
            FlowRunPrcs nextFrp = new FlowRunPrcs();
            List<FlowRunPrcs> result = new ArrayList<FlowRunPrcs>();
            List<FlowRunPrcs> child = new ArrayList<FlowRunPrcs>();

            //0 显示 1 隐藏
            for (int i = 0, size = list.size(); i < size; i++) {
                frp = list.get(i);
                if (i < list.size() - 1) {
                    nextFrp = list.get(i + 1);
                    if (frp.getRunId().equals(nextFrp.getRunId())) {
                        frp.setHavaSon("0");
                    } else {
                        frp.setHavaSon("1");
                    }
                    frp.setIsHidden("0");
                    if (mAll.containsKey(frp.getRunId())) {
                        frp.setIsHidden("1");
                    } else {
                        child.add(frp);
                        mAll.put(frp.getRunId(), child);
                    }
                } else {
                    if (mAll.containsKey(frp.getRunId())) {
                        frp.setIsHidden("1");
                        frp.setHavaSon("1");
                    } else {
                        frp.setIsHidden("0");
                        frp.setHavaSon("1");
                    }
                }
            }


            int len = list.size();
            if (len > 0) {
                toJson.setTotleNum(pageParams.getTotal());
                for (FlowRunPrcs flowRunPrcs : list) {
                    Map<String, Object> m = new HashMap<String, Object>();
                    m.put("runId", flowRunPrcs.getRunId());
                    FlowRun flowRun = wfeFlowRunMapper.find(m);
                    //List<FlowRunPrcs> flowRunPrcsList = flowRunPrcsMapper.findByRunId(flowRunPrcs.getRunId());
                    //查询下一步的流程
                    Map<String, Object> map1 = new HashMap<String, Object>();
                    map1.put("prcsId", flowRunPrcs.getPrcsId() + 1);
                    map1.put("runId", flowRunPrcs.getRunId());
                    List<FlowRunPrcs> nextFlowRunPrcsList = wfeFlowRunPrcsMapper.findNextFrp(map1);
                    //查询流程最后一步
                    List<FlowRunPrcs> maxFrp = wfeFlowRunPrcsMapper.findMaxFrp(flowRunPrcs.getRunId());

                    if (nextFlowRunPrcsList.size() == 1) {
                        FlowRunPrcs flowRunPrcs1 = nextFlowRunPrcsList.get(0);
                        if (flowRunPrcs1.getPrcsFlag().equals("1")) {
                            flowRunPrcs.setState1("已转交，下一步未接收");
                        } else if (flowRunPrcs1.getPrcsFlag().equals("2")) {
                            flowRunPrcs.setState1("已转交，下一步办理中");
                        } else if (flowRunPrcs1.getPrcsFlag().equals("3")) {
                            flowRunPrcs.setState1("已转交，下一步已转交");
                        } else if (flowRunPrcs1.getPrcsFlag().equals("4")) {
                            flowRunPrcs.setState1("已转交，下一步已办结");
                        } else if (flowRunPrcs1.getPrcsFlag().equals("6")) {
                            flowRunPrcs.setState1("已转交，下一步已挂起");
                        }
                    } else {
                        List<String> list1 = new ArrayList<String>();
                        int one = 0;
                        int two = 0;
                        int three = 0;
                        int four = 0;
                        for (FlowRunPrcs flowRunPrcs1 : nextFlowRunPrcsList) {
                            if (flowRunPrcs1.getPrcsFlag().equals("1")) {
                                one++;
                            } else if (flowRunPrcs1.getPrcsFlag().equals("2")) {
                                two++;
                            } else if (flowRunPrcs1.getPrcsFlag().equals("3")) {
                                three++;
                            } else if (flowRunPrcs1.getPrcsFlag().equals("4")) {
                                four++;
                            }
                        }
                        if (one == nextFlowRunPrcsList.size()) {
                            flowRunPrcs.setState1("已转交，下一步未接收");
                        } else if (three == nextFlowRunPrcsList.size()) {
                            flowRunPrcs.setState1("已转交，下一步已办结");
                        } else {
                            flowRunPrcs.setState1("已转交，下一步办理中");
                        }
                    }
                    if (maxFrp.size() > 1) {
                        flowRunPrcs.setState2("1");
                    } else {
                        FlowRunPrcs flowRunPrcs3 = maxFrp.get(0);
                        flowRunPrcs.setState2("0");

                        Map<String, Object> map = new HashMap<String, Object>();
                        map.put("runId", flowRunPrcs3.getRunId());
                        map.put("prcsId", flowRunPrcs3.getFlowPrcs());
                        String prcsName1 = flowProcessMapper.findPrcsName(map);
                        String prcsName ="";
                        if(!StringUtils.checkNull(prcsName1)){
                            prcsName="第" + flowRunPrcs3.getPrcsId() + "步:" + prcsName1;
                        }else{
                            prcsName="第" + flowRunPrcs3.getPrcsId() + "步:" + "此步骤已删除";
                        }

                        flowRunPrcs.setBz(prcsName);
                        flowRunPrcs.setCurrentPeople(usersService.getUserNameById(flowRunPrcs3.getUserId()));
                    }

                    if (StringUtils.checkNull(flowRun.getEndTime())) {
                        flowRunPrcs.setState("执行中");
                    } else {
                        flowRunPrcs.setState("已结束");
                        flowRunPrcs.setState1("流程已结束");
                    }
                    flowRunPrcs.setFlowRun(flowRun);
                    flowRunPrcs.getFlowRun().setUserName(usersService.getUserNameById(flowRunPrcs.getBeginUser()));
                 /*   flowRunPrcs.getFlowRun().setFlowId(flowRunPrcs.getFlowId());
                    flowRunPrcs.getFlowRun().setRunName(flowRunPrcs.getRunName());
                    flowRunPrcs.getFlowRun().setWorkLevel(Integer.parseInt(flowRunPrcs.getWorkLevel()));*/
                    flowRunPrcs.setUserName(usersService.getUserNameById(flowRun.getBeginUser()));
                    flowRunPrcs.setFlowType(flowTypeModelMapper.queryOneObject(flowRunPrcs.getFlowId()));
                    //查询流程并设置流程
                    FlowProcess flowProcess = flowProcessMapper.findProcess(flowRunPrcs.getFlowId(), flowRunPrcs.getFlowPrcs());
                    if (flowProcess != null) {
                        flowRunPrcs.setFlowProcess(flowProcess);
                    }
                    if (!StringUtils.checkNull(flowRunPrcs.getDeliverTime())) {
                        flowRunPrcs.setDeliverTime(DateFormat.getStrTime(DateFormat.getTime(flowRunPrcs.getDeliverTime())));
                    }
                    //returnList.add(flowRunPrcs);

                    //到达时长
                    if (!StringUtils.checkNull(flowRunPrcs.getDeliverTime()) && !StringUtils.checkNull(flowRunPrcs.getCreateTime())) {
                        flowRunPrcs.setArriveTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(new Date()))) - DateFormat.getTime(flowRunPrcs.getCreateTime())));
                    }
                    // 办理时长
                    if (!StringUtils.checkNull(flowRunPrcs.getDeliverTime()) && !StringUtils.checkNull(flowRunPrcs.getPrcsTime())) {
                        flowRunPrcs.setHandleTime(DateFormat.returnTime((DateFormat.getTime(flowRunPrcs.getDeliverTime())) - DateFormat.getTime(flowRunPrcs.getPrcsTime())));
                    }
                    if (!StringUtils.checkNull(flowRunPrcs.getCreateTime())) {
                        flowRunPrcs.setCreateTime(flowRunPrcs.getCreateTime().substring(0, flowRunPrcs.getCreateTime().length() - 2));
                    }
                    if (!StringUtils.checkNull(flowRunPrcs.getPrcsTime())) {
                        flowRunPrcs.setPrcsTime(flowRunPrcs.getPrcsTime().contains("1950") ? "" : flowRunPrcs.getPrcsTime().substring(0, flowRunPrcs.getPrcsTime().length() - 2));
                    }
                    flowRunPrcs.setJbbz("第" + flowRunPrcs.getPrcsId() + "步:" + flowRunPrcs.getPrcsName());


                    //查询当前流程能否传阅
                    Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
                    Users users = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(),redisSessionCookie);
                    //BaseWrappers flowRunPrecsAll = wfeFlowProcess.getFlowRunPrecsAll(String.valueOf(flowRunPrcs.getRunId()));
                    List<FlowRunPrcs> flowRunReacsAllByRunId = wfeFlowRunPrcsMapper.getFlowRunReacsAllByRunIdEnd(String.valueOf(flowRunPrcs.getRunId()));
                    for (FlowRunPrcs flowRuns:flowRunReacsAllByRunId){
                        if (users.getUserId().equals(flowRuns.getUserId())){
                            flowRunPrcs.setChuan("1");
                        }
                    }

                    // 查询当前流程是否有查阅情况
                    try {
                        Map<String,Object> mapss = new HashMap<String,Object>();
                        mapss.put("runId", flowRunPrcs.getRunId());
                        List<FlowRunRead> flowRunReads = toBeReadMapper.ReadFileIsRead(mapss);
                        if (flowRunReads.size()>0){
                            flowRunPrcs.setReadInfo("1");
                        }
                    }catch (Exception e){

                    }

                }
                toJson.setFlag(0);
                toJson.setMsg("ok");
                toJson.setObj(list);
            }
        } catch (Exception e) {
            toJson.setFlag(1);
            toJson.setMsg(e.getMessage());
        }
        return toJson;
    }


    /**
     * 创建作者:   张勇
     * 创建日期:   2017/5/25 15:47
     * 方法介绍:   查询所有工作
     * 参数说明:
     *
     * @return
     */
    public ToJson<FlowRunPrcs> selectAll(Map<String, Object> maps, Integer page, Integer pageSize, boolean useFlag) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>(1, "error");
        PageParams pages = new PageParams();
        pages.setPage(page);
        pages.setPageSize(pageSize);
        pages.setUseFlag(useFlag);
        maps.put("page", pages);
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectAll(maps);
        List<FlowRunPrcs> returnList = new ArrayList<FlowRunPrcs>();
        int len = list.size();
        if (len > 0) {
            toJson.setTotleNum(pages.getTotal());
            for (FlowRunPrcs flowRunPrcs : list) {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("runId", flowRunPrcs.getRunId());
                FlowRun flowRun = wfeFlowRunMapper.find(map);
                if (StringUtils.checkNull(flowRun.getEndTime())) {
                    flowRunPrcs.setState("执行中");
                } else {
                    flowRunPrcs.setState("已结束");
                }
                flowRunPrcs.getFlowRun().setUserName(usersService.getUserNameById(flowRunPrcs.getFlowRun().getBeginUser()));
                flowRunPrcs.setUserName(usersService.getUserNameById(flowRunPrcs.getUserId()));
                flowRunPrcs.setFlowType(flowTypeModelMapper.queryOneObject(flowRunPrcs.getFlowRun().getFlowId()));
                FlowProcess flowProcess = flowProcessMapper.findProcess(flowRunPrcs.getFlowRun().getFlowId(), flowRunPrcs.getFlowPrcs());
                if (flowProcess != null) {
                    flowRunPrcs.setFlowProcess(flowProcess);
                }
                returnList.add(flowRunPrcs);
                flowRunPrcs.setJbbz("第" + flowRunPrcs.getPrcsId() + "步:" + flowRunPrcs.getFlowProcess().getPrcsName());
            }

            toJson.setFlag(0);
            toJson.setMsg("ok");
            toJson.setObj(returnList);
        } else {
            toJson.setFlag(1);
            toJson.setMsg("error");
        }
        return toJson;
    }

    /**
     * 方法介绍:   查询挂起工作
     * 参数说明:
     *
     * @return
     */
    public ToJson<FlowRunPrcs> selectHang(Map<String, Object> maps, Integer page,
                                          Integer pageSize, boolean useFlag) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>();
        PageParams pageParams = new PageParams();
        pageParams.setPage(page);
        pageParams.setPageSize(pageSize);
        pageParams.setUseFlag(useFlag);
        maps.put("page", pageParams);
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectHang(maps);
        List<FlowRunPrcs> returnList = new ArrayList<FlowRunPrcs>();
        int len = list.size();
        if (len > 0) {
            toJson.setTotleNum(pageParams.getTotal());
            for (FlowRunPrcs flowRunPrcs : list) {
                flowRunPrcs.setUserName(usersService.getUserNameById(flowRunPrcs.getUserId()));
                flowRunPrcs.setFlowType(flowTypeModelMapper.queryOneObject(flowRunPrcs.getFlowRun().getFlowId()));
                returnList.add(flowRunPrcs);
            }
            toJson.setFlag(0);
            toJson.setMsg("ok");
            toJson.setObj(returnList);
        } else {
            toJson.setFlag(1);
            toJson.setMsg("error");
        }
        return toJson;
    }


    /**
     * 创建作者:   zlf
     * 创建日期:   2017/11/9 17:04
     * 方法介绍:   查询是否强制转交
     * 参数说明:
     *
     * @return
     */
    public Integer checkGatherNode(Map<String, Object> maps) {
        return wfeFlowRunPrcsMapper.checkGatherNode(maps);
    }

    /**
     * 检查强制合并对应流程是否办完
     *
     * @param maps
     * @return
     */
    public Integer checkBranchCount(Map<String, Object> maps) {
        return wfeFlowRunPrcsMapper.checkBranchCount(maps);
    }

    //工作监控
    public AjaxJson monitoring(Map<String, Object> maps, Integer page,
                               Integer pageSize, boolean useFlag, String output, HttpServletRequest request, HttpServletResponse response) {
        AjaxJson ajaxJson = new AjaxJson();
        PageParams pages = new PageParams();
        if (!"1".equals(output)) {
            pages.setPage(page);
            pages.setPageSize(pageSize);
            pages.setUseFlag(useFlag);
            maps.put("page", pages);
        }
        try {
            //获取当前用户对应查询范围权限的sql
            String myManage = wfeFlowRun.getAllQueryPriv((Users) maps.get("user"), "2");
            maps.put("myManage", myManage);
            //查询所有工作监控
            List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.monitoring(maps);
            for (FlowRunPrcs flowRunPrcs : list) {
                String time = reTime(flowRunPrcs.getPrcsTime());
                flowRunPrcs.setHandleTime(time);

                Map<String, Object> map = new HashMap<>();
                map.put("flowId", flowRunPrcs.getFlowId());
                map.put("prcsId", flowRunPrcs.getFlowPrcs());
                FlowProcess flowProcess = flowProcessMapper.findbyprcsId(map);
                if (flowProcess != null) {
                    flowRunPrcs.setAllowBack(flowProcess.getAllowBack());
                    flowRunPrcs.setPrcsName(flowProcess.getPrcsName());
                }

                String step1 = "第" + flowRunPrcs.getPrcsId() + "步" + ":" + flowRunPrcs.getPrcsName();
                flowRunPrcs.setPrcsName(step1);
                if (!StringUtils.checkNull(flowRunPrcs.getOpFlag()) && flowRunPrcs.getOpFlag().equals("1")) {
                    flowRunPrcs.setUserName("主办：" + flowRunPrcs.getUserName());
                } else {
                    flowRunPrcs.setUserName("经办：" + flowRunPrcs.getUserName());
                }
                Date date = new Date();
                if (Integer.parseInt(flowRunPrcs.getPrcsFlag()) <= 2) {
                    // 办理时长
                    if (DateFormat.getTime(flowRunPrcs.getPrcsTime()) == -621701856) {
                        flowRunPrcs.setHandleTime("未接收");
                        flowRunPrcs.setPrcsTime("");
                    } else {
                        flowRunPrcs.setHandleTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(date))) - DateFormat.getTime(flowRunPrcs.getPrcsTime())));
                        flowRunPrcs.setPrcsTime(flowRunPrcs.getPrcsTime().substring(0, 19));
                    }
                } else {
                    //办理时间
                    flowRunPrcs.setHandleTime(DateFormat.returnTime((DateFormat.getTime(flowRunPrcs.getDeliverTime())) - DateFormat.getTime(flowRunPrcs.getPrcsTime())));
                }
                flowRunPrcs.setBz(flowRunPrcs.getPrcsTime() + flowRunPrcs.getHandleTime());



   /*             List<FlowRunPrcs> stepList=wfeFlowRunPrcsMapper.selByRunId(flowRunPrcs.getRunId());

                for(FlowRunPrcs flowStep:stepList){
                    String createTime = this.reTime(flowStep.getPrcsTime());
                    flowStep.setHandleTime(createTime);
                    String step = "第"+flowStep.getPrcsId()+"步"+":"+flowStep.getPrcsName();
                    flowStep.setPrcsName(step);
                    if(!StringUtils.checkNull(flowStep.getOpFlag()) && flowStep.getOpFlag().equals("1")){
                        flowStep.setUserName("主办："+flowStep.getUserName());
                    }else{
                        flowStep.setUserName("经办："+flowStep.getUserName());
                    }
                    Date newDate = new Date();
                    if (Integer.parseInt(flowStep.getPrcsFlag())<=2){
                        // 办理时长
                        if (DateFormat.getTime(flowStep.getPrcsTime()) == -621701856){
                            flowStep.setHandleTime("未接收");
                            flowStep.setPrcsTime("");
                        }else {
                            flowStep.setHandleTime(DateFormat.returnTime((DateFormat.getTime(DateFormat.getStrDate(newDate)))-DateFormat.getTime(flowStep.getPrcsTime())));

                        }
                    }else {
                        //办理时间
                        flowStep.setHandleTime(DateFormat.returnTime((DateFormat.getTime(flowStep.getDeliverTime()))-DateFormat.getTime(flowStep.getPrcsTime())));
                    }


                    Map<String,Object> map1=new HashMap<>();
                    map.put("flowId",flowStep.getFlowId());
                    map.put("prcsId",flowStep.getFlowPrcs());
                    FlowProcess flowProcess1 = flowProcessMapper.findbyprcsId(map);
                    if(flowProcess1!=null){
                        flowStep.setAllowBack(flowProcess1.getAllowBack());
                    }
                }*/
                // flowRunPrcs.setFlowStep(stepList);
            }
            if ("1".equals(output)) {//output==1,则进行导出操作
                HSSFWorkbook tableWork = ExcelUtil.makeExcelHead("工作监控", 15);
                String[] secondTitles = {"流水号", "流程类型", "工作名称/文号", "当前步骤", "当前办理人", "办理时间"};
                HSSFWorkbook excelWork = ExcelUtil.makeSecondHead(tableWork, secondTitles);
                String[] beanProperty = {"runId", "flowName", "runName", "prcsName", "userName", "bz"};
                HSSFWorkbook workbook = ExcelUtil.exportExcelData(excelWork, list, beanProperty);
                response.setContentType("text/html;charset=UTF-8");
                OutputStream out = response.getOutputStream();

                String filename = "工作监控.xls"; //考虑多语言
                filename = FileUtils.encodeDownloadFilename(filename,
                        request.getHeader("user-agent"));
                response.setContentType("application/vnd.ms-excel");
                response.setHeader("content-disposition",
                        "attachment;filename=" + filename);
                workbook.write(out);
                out.flush();
                out.close();
            }
            ajaxJson.setTotleNum(pages.getTotal());
            ajaxJson.setMsg("OK");
            ajaxJson.setFlag(true);
            ajaxJson.setObj(list);
        } catch (Exception e) {
            e.printStackTrace();
            ajaxJson.setMsg("false");
            ajaxJson.setFlag(false);
        }
        return ajaxJson;
    }


    /**
     * 创建作者:   张勇
     * 创建日期:   2017/6/20 13:52
     * 方法介绍:   删除我的工作待办第一步
     * 参数说明:
     *
     * @return
     */
    @Transactional
    public ToJson<FlowRunPrcs> deleteRunPrcs(FlowRunPrcs flowRunPrcs) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>(1, "error");
        try {
            this.deleteWorkFlow(flowRunPrcs.getId());
            toJson.setFlag(0);
            toJson.setMsg("ok");
           /* } else {
                //重名
                toJson.setMsg("repetition");
            }*/
        } catch (Exception e) {
            L.e("FlowRunPrcsService deleteRunPrcs:" + e);
            toJson.setFlag(1);
            toJson.setMsg(e.getMessage());
        }
        return toJson;
    }


    /**
     * 创建作者:
     * 创建日期:   2018/6/7 13:52
     * 方法介绍:   批量删除我的工作待办
     * 参数说明:
     *
     * @return
     */
    @Transactional
    public ToJson<FlowRunPrcs> deleteRunPrcsBatch(String idBatch) {
        ToJson<FlowRunPrcs> toJson = new ToJson<FlowRunPrcs>();
        try {
            String[] ids = idBatch.split(",");
            for (int i = 0; i < ids.length; i++) {
                this.deleteWorkFlow(Integer.parseInt(ids[i]));
            }
            toJson.setFlag(0);
            toJson.setMsg("ok");
        } catch (Exception e) {
            L.e("FlowRunPrcsService deleteRunPrcs:" + e);
            toJson.setFlag(1);
            toJson.setMsg(e.getMessage());
        }
        return toJson;
    }


    //工作结束 prcsFlag、deliverTime、runId
    @Transactional
    public int updateEnd(Map<String, Object> map) {
        List<FlowRunPrcs> maxFrps = wfeFlowRunPrcsMapper.findMaxFrp(Integer.parseInt(map.get("runId").toString()));
        if(maxFrps.size()>0){
            StringBuffer sb = new StringBuffer();
            for (FlowRunPrcs flowRunPrcs : maxFrps) {
                sb.append(flowRunPrcs.getPrcsId() + "`" + flowRunPrcs.getPrcsFlag() + "`" + flowRunPrcs.getFlowPrcs() + "`" + flowRunPrcs.getUserId() + ",");
                map.put("prcsId",flowRunPrcs.getPrcsId());
            }
            map.put("forceOver", sb.toString());
        }
        int a = wfeFlowRunPrcsMapper.updateEnd(map);
        a += wfeFlowRunMapper.updateState(map);
        return a;
    }

    //工作撤回
    public AjaxJson workBack(Integer prcsId, Integer flowPrcs, String runId, String userId, String tabId, String tableName) {
        AjaxJson ajaxJson = new AjaxJson();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("prcsId", prcsId);
        map.put("flowPrcs", flowPrcs);
        map.put("runId", runId);
        map.put("prcsFlag2", 34);
        /// 注释了是否主办
        // map.put("opFlag", 1);
        try {

            //查询当前
            List<FlowRunPrcs> flowRunPrcs = wfeFlowRunPrcsMapper.selectFind(map);
            if (flowRunPrcs != null && flowRunPrcs.size() > 0) {
                map.put("runId", runId);
                FlowRun flowRun = wfeFlowRunMapper.find(map);
                map.put("prcsId", prcsId + 1);
                map.put("flowPrcs", null);
                map.put("prcsFlag", null);
                map.put("opFlag", null);
                //查询当前步骤
                List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectFind(map);
                boolean flag =true;
                for (FlowRunPrcs f : list) {
                  if (Integer.parseInt(f.getPrcsFlag())>2){
                      flag =false;
                      break;
                  }
                }
                if (flag){
                    //删除可回退步骤
                    wfeFlowRunPrcsMapper.deleteBycondition(map);

                    //更新当前步骤
                    map.put("prcsId", prcsId);
                    map.put("flowPrcs", flowPrcs);
                    map.put("runId", runId);
                    map.put("prcsFlag", 2);
                    map.put("opFlag", null);
                    map.put("deliverTime", "2000-01-01 00:00:00");
                    wfeFlowRunPrcsMapper.updateSome(map);
                    //主办
                    FlowRunPrcs flowRunPrcs1 = null;
                    String smsUrl = null;
                    for (int i = 0; i < list.size(); i++) {
                        flowRunPrcs1 = list.get(0);
                        smsUrl = "/workflow/work/workform?opflag=1&flowId=" + flowRun.getFlowId() + "&flowStep=" + (prcsId + 1) + "&runId=" + runId + "&prcsId=" + flowRunPrcs1.getFlowPrcs();
                        smsBodyMapper.deleteWorkBackSms(smsUrl);
                    }
                    //如果有传阅功能
                    FlowRun flowRun1 = wfeFlowRun.find(Integer.valueOf(runId));
                    if (!"".equals(flowRun1.getViewUser()) && flowRun1.getViewUser() != null) {
                        Map map1 = new HashMap();
                        map1.put("runId", runId);
                        map1.put("prcsId", prcsId);
                        map1.put("flowPrcs", flowPrcs);
                        //删除全部步骤的传阅
                        toBeReadMapper.deleteWockBackFlowRunRead(map1);
                        String smsUrlStr = "";
                        String smsUrlStr1 = "";
                        //删除全部步骤传阅的事务提醒
                        if (!"".equals(tabId) && tabId != null) { //如果是公文
                            Integer prcaId = flowRunPrcs1.getFlowPrcs() - 1;
                            smsUrlStr = "/workflow/work/workform?opflag=1&flowId=" + flowRun.getFlowId() + "&flowStep=" + (prcsId + 1) + "&tableName=" + tableName + "&tabId=" + tabId + "&runId=" + runId + "&prcsId=" + flowRunPrcs1.getFlowPrcs() + "&isNomalType=false";
                            smsUrlStr1 = "/workflow/work/workformPreView?flowId=" + flowRun.getFlowId() + "&flowStep=" + (prcsId) + "&tableName=" + tableName + "&tabId=" + tabId + "&runId=" + runId + "&prcsId=" + prcaId + "&isNomalType=false&hidden=true";

                        } else {//工作流
                            Integer prcaId = flowRunPrcs1.getFlowPrcs() - 1;
                            smsUrlStr = "/workflow/work/workform?opflag=1&flowId=" + flowRun.getFlowId() + "&flowStep=" + (prcsId + 1) + "&runId=" + runId + "&prcsId=" + flowRunPrcs1.getFlowPrcs();
                            smsUrlStr1 = "/workflow/work/workform?opflag=1&flowId=" + flowRun.getFlowId() + "&flowStep=" + prcsId + "&runId=" + runId + "&prcsId=" + prcaId;
                        }
                        smsBodyMapper.deleteWorkBackSms(smsUrlStr1);
                        smsBodyMapper.deleteWorkBackSms(smsUrlStr);
                    }
                    ajaxJson.setFlag(true);
                    ajaxJson.setMsg("OK");
                    /**     lr 工作流使用添加日志 ----收回**/
                    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                    FlowRunLog flowRunLog = wfeLog.getFlowRunLogByRequest(request);
                    //装配日志对象
                    flowRunLog.setType(Constant.TYPE4);
                    flowRunLog.setRunId(Integer.parseInt(runId));
                    flowRunLog.setFlowPrcs(flowPrcs);
                    flowRunLog.setPrcsId(prcsId);

                    //添加日志
                    wfeLog.addFlowRunLog(flowRunLog);
                    return ajaxJson;
                }

            }
            ajaxJson.setFlag(false);
            ajaxJson.setMsg("收回失败，流程已办理");
        } catch (Exception e) {
            e.printStackTrace();
            ajaxJson.setFlag(false);
            ajaxJson.setMsg("收回失败");
        }
        return ajaxJson;
    }


    //提醒指定步骤经办人
    public AjaxJson remindSteps(Integer prcsId, String runId) {
        AjaxJson ajaxJson = new AjaxJson();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("prcsId", prcsId);
        map.put("runId", runId);
        map.put("opFlag", null);
        try {
            //所有经办人流程
            List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectStep(map);
            //定义抛给前台参数
            Map<Integer, List<FlowRunPrcs>> mapList = new HashMap<Integer, List<FlowRunPrcs>>();
            List<FlowRunPrcs> flowRunPrcsList = null;
            ;
            for (FlowRunPrcs flowRunPrcs : list) {
                String prcsName = "第" + flowRunPrcs.getPrcsId() + "步:" + flowProcessMapper.findPrcsName(map);
                Users users = usersService.findUsersByuserId(flowRunPrcs.getUserId());
                flowRunPrcs.setPrcsName(prcsName);
                flowRunPrcs.setUsers(users);
                if (map.keySet().contains(flowRunPrcs.getPrcsId())) {
                    flowRunPrcsList = mapList.get(flowRunPrcs.getPrcsId());
                    flowRunPrcsList.add(flowRunPrcs);
                } else {
                    flowRunPrcsList = new ArrayList<FlowRunPrcs>();
                    flowRunPrcsList.add(flowRunPrcs);
                    mapList.put(flowRunPrcs.getPrcsId(), flowRunPrcsList);
                }

            }
            ajaxJson.setObj(mapList);
            ajaxJson.setFlag(true);
            ajaxJson.setMsg("OK");
        } catch (Exception e) {
            e.printStackTrace();
            ajaxJson.setFlag(false);
            ajaxJson.setMsg("false");
        }
        return ajaxJson;
    }


    public AjaxJson entrustWork(Map<String, Object> maps, Integer page,
                                Integer pageSize, boolean useFlag) {
        AjaxJson ajaxJson = new AjaxJson();
        PageParams pages = new PageParams();
        pages.setPage(page);
        pages.setPageSize(pageSize);
        pages.setUseFlag(useFlag);
        maps.put("page", pages);
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.entrustWork(maps);
        int len = list.size();
        if (len > 0) {
            ajaxJson.setTotleNum(pages.getTotal());
            for (FlowRunPrcs flowRunPrcs : list) {
                flowRunPrcs.setUserName(usersService.getUserNameById(flowRunPrcs.getUserId()));
                flowRunPrcs.setFlowType(flowTypeModelMapper.queryOneObject(flowRunPrcs.getFlowRun().getFlowId()));
                FlowProcess flowProcess = flowProcessMapper.findProcess(flowRunPrcs.getFlowRun().getFlowId(), flowRunPrcs.getFlowPrcs());
                if (flowProcess != null) {
                    flowRunPrcs.setFlowProcess(flowProcess);
                }
            }
        }

        return null;

    }


    public static String reTime(String prcsTime) throws Exception {
        String format = "yyyy-MM-dd HH:mm:ss";
        long aString = System.currentTimeMillis() / 1000;
        Integer time = Integer.parseInt(String.valueOf(aString));

        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Long aa = sdf.parse(prcsTime).getTime() / 1000;

        Integer end = Integer.parseInt(String.valueOf(aa));
        Integer re = time - end;
        String aString3 = DateFormat.returnTime(re);
        return aString3;
    }

    public FlowRunPrcs getLastPrcsByRunId(Integer runId) {
        return wfeFlowRunPrcsMapper.getLastPrcsByRunId(runId);
    }


    //查询经办
    public List<FlowRunPrcs> selectOp(Map<String, Object> maps) {
        return wfeFlowRunPrcsMapper.selectOp(maps);
    }


    //先接受者主办
    public void updateOpflag(Map<String, Object> maps) {
        wfeFlowRunPrcsMapper.updateOpflag(maps);
    }


    /**
     * 创建作者:   张龙飞
     * 方法介绍:   根据部分条件查询流程实例步骤信息
     * 参数说明:
     *
     * @return
     */
    public List<FlowRunPrcs> selectCondition(Map<String, Object> maps) {
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectCondition(maps);
        return list;
    }


    /**
     * 创建作者:   牛江丽
     * 创建日期:   2018/1/22 13:52
     * 方法介绍:   恢复执行
     * 参数说明：
     *
     * @return
     */
    public ToJson resumeExe(String runId, Integer id) {
        ToJson<FlowRunPrcs> toJson = new ToJson<>(1, "error");
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            FlowRunLog flowRunLog = wfeLog.getFlowRunLogByRequest(request);

            Map<String, Object> map = new HashMap<String, Object>();
            String[] runIdArr = runId.split(",");
            int count = 0;
            for (int j = 0; j < runIdArr.length; j++) {
                String runIdStr = runIdArr[j];

                map.put("runId", runIdStr);
                FlowRun flowRun = wfeFlowRunMapper.find(map);
                List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.findMaxFrp(Integer.valueOf(runIdStr));
                FlowRunPrcs flowRunPrcs = null;



                //强制结束恢复流程
                if (!StringUtils.checkNull(flowRun.getForceOver())) {
                    String[] forceOverAll = flowRun.getForceOver().split(",");
                    for (int i = 0; i < forceOverAll.length; i++) {
                        flowRunPrcs = list.get(i);
                        String[] forceOver = forceOverAll[i].split("`");
                        flowRunPrcs.setId(flowRunPrcs.getId());
                        flowRunPrcs.setPrcsId(Integer.valueOf(forceOver[0]));
                        flowRunPrcs.setPrcsFlag(forceOver[1]);
                        flowRunPrcs.setFlowPrcs(Integer.valueOf(forceOver[2]));
                        flowRunPrcs.setUserId(forceOver[3]);
                        if (forceOver[1] != "3" && forceOver[1] != "4") {
                            flowRunPrcs.setDeliverTime("2000-01-01 00:00:00");
                        }
                        flowRun.setEndTime("2000-01-01 00:00:00");
                        flowRun.setForceOver("");
                        count += wfeFlowRunPrcsMapper.upPrcsStatusById(flowRunPrcs);
                        count += wfeFlowRunMapper.upRunByFouAndTime(flowRun);

                        //日志
                        flowRunLog.setFlowPrcs(Integer.valueOf(forceOver[2]));
                        flowRunLog.setPrcsId(Integer.valueOf(forceOver[0]));
                        flowRunLog.setContent("强制恢复此工作");

                    }
                }else{
                    //正常流程结束流程
                    flowRunPrcs = list.get(0);
                    //步骤状态改为2办理中
                    flowRunPrcs.setPrcsFlag("2");
                    //结束时间
                    flowRunPrcs.setDeliverTime("2000-01-01 00:00:00");
                    flowRun.setEndTime("2000-01-01 00:00:00");
                    count += wfeFlowRunPrcsMapper.upPrcsStatusById(flowRunPrcs);
                    count += wfeFlowRunMapper.upRunByFouAndTime(flowRun);

                    //装配日志对象
                    flowRunLog.setFlowPrcs(flowRunPrcs.getFlowPrcs());
                    flowRunLog.setPrcsId(flowRunPrcs.getPrcsId());
                    flowRunLog.setContent("流程正常结束恢复此工作");
                }

                //装配日志对象
                flowRunLog.setType("9");
                flowRunLog.setRunId(Integer.valueOf(runIdStr));
                wfeLog.addFlowRunLog(flowRunLog);
            }

            if (count > 0) {
                toJson.setFlag(0);
                toJson.setMsg("ok");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return toJson;
    }


    public int updateGather(Map<String, Object> map) {
        return wfeFlowRunPrcsMapper.updateGather(map);
    }


    public Integer checkBranch(Integer runId, String branchCount, Integer flowPrcs) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("runId", runId);
        map.put("branchCount", branchCount);
        map.put("flowPrcs", flowPrcs);
        return wfeFlowRunPrcsMapper.checkBranch(map);
    }


    public int updatePrcsId(Integer runId, Integer prcsId, String userId, String prcsFlag, Integer flowPrcs, String branchCount) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("runId", runId);
        map.put("prcsId", prcsId);
        map.put("userId", userId);
        map.put("prcsFlag", prcsFlag);
        map.put("flowPrcs", flowPrcs);
        map.put("branchCount", branchCount);
        return wfeFlowRunPrcsMapper.updatePrcsId(map);
    }

    public int updateParent(Integer runId, Integer prcsId, String userId, String prcsFlag,
                            Integer flowPrcs, String branchCount, String parent, String parentPrcsId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("runId", runId);
        map.put("prcsId", prcsId);
        map.put("userId", userId);
        map.put("prcsFlag", prcsFlag);
        map.put("flowPrcs", flowPrcs);
        map.put("branchCount", branchCount);
        map.put("parent", parent);
        map.put("parentPrcsId", parentPrcsId);
        return wfeFlowRunPrcsMapper.updateParent(map);
    }


    //流程信息删除
    public void deleteWorkFlow(Integer Id) {
        //根据流程是否在第一步判断是否可以删除
        Integer flag = wfeFlowRunPrcsMapper.selectPrcs(Id);
        if (flag == 1) {
            Map<String, Object> map = new HashMap<String, Object>();
            //获取此步骤流程实例信息
            FlowRunPrcs flowRunPrcs = wfeFlowRunPrcsMapper.selectByPrimaryKey(Id);
            map.put("runId", flowRunPrcs.getRunId());
            //获取流程实例基本信息
            FlowRun flowRun = wfeFlowRunMapper.find(map);
            Integer runId = flowRunPrcs.getRunId();
            //添加我的工作中删除日志
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            FlowRunLog flowRunLog = wfeLog.getFlowRunLogByRequest(request);
            flowRunLog.setRunId(runId);
            flowRunLog.setType(Constant.TYPE17);
            flowRunLog.setPrcsId(flowRunPrcs.getPrcsId());
            flowRunLog.setFlowPrcs(flowRunPrcs.getFlowPrcs());
            wfeLog.addFlowRunLog(flowRunLog);
            //删除流程实例步骤信息
            wfeFlowRunPrcsMapper.deleteWork(flowRunPrcs);
            //删除流程实例基本信息
            wfeFlowRunMapper.deleteByRunId(runId);
            //删除会签意见
            flowRunFeedbackMapper.delFlowRunFeedBack(runId);
            //删除对应公文信息
            DocumentModelWithBLOBs documentModelWithBLOBs = new DocumentModelWithBLOBs();
            documentModelWithBLOBs.setId(runId);
            documentSerivce.deleteDocument(documentModelWithBLOBs);
            //删除流程日志数据
//            flowRunLogMapper.delFlowRunLogByRunId(runId);
            //删除流程业务数据
            map.put("tableName", "flow_data_" + flowRun.getFlowId());
            String sqlType = "xoa" + (String) request.getSession().getAttribute(
                    "loginDateSouse");
            if (StringUtils.checkNull((String) request.getSession().getAttribute(
                    "loginDateSouse"))) {
                sqlType = "xoa1001";
            }
            if (StringUtils.checkNull(sqlType)) {
                map.put("tableSchema", "xoa1001");
            } else {
                map.put("tableSchema", sqlType);
            }
            //判断流程数据信息表是否存在
            List<String> columns = workMapper.showColumns(map);
            if (columns.size() != 0) {
                workMapper.deWork(map);
            }
        }
    }

    public List<FlowRunPrcs> getFlowRunReacsAllByRunId(String runId) {
        return wfeFlowRunPrcsMapper.getFlowRunReacsAllByRunId(runId);
    }

    /**
     * @创建作者:李然 Lr
     * @方法描述：获取我的委托
     * @创建时间：20:01 2019/5/19
     **/
    public ToJson<FlowRunPrcs> entrustWorkList(HttpServletRequest request, PageParams pageParams) {
        ToJson toJson = new ToJson();
        Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
        Users user = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
        Map map = new HashMap();
        map.put("userId", user.getUserId());
        map.put("page", pageParams);
        String myworkconditions = request.getParameter("myworkconditions");
        String flowId = request.getParameter("flowId");
        if (myworkconditions != null && !myworkconditions.equals("")) {
            map.put("myworkconditions", "%" + myworkconditions + "%");
        }
        if (flowId != null && !flowId.equals("")) {
            map.put("flowId", flowId);
        }
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.getEntrustWorkList(map);
        if (list != null && list.size() > 0) {
            for (FlowRunPrcs flowRunPrcs : list) {
                flowRunPrcs.setUserName(usersService.getUserNameById(flowRunPrcs.getUserId()));
                flowRunPrcs.setFlowType(flowTypeModelMapper.queryOneObject(flowRunPrcs.getFlowRun().getFlowId()));
                FlowProcess flowProcess = flowProcessMapper.findProcess(flowRunPrcs.getFlowRun().getFlowId(), flowRunPrcs.getFlowPrcs());
                if (flowProcess != null) {
                    flowRunPrcs.setFlowProcess(flowProcess);
                }
                Map<String, Object> m = new HashMap<String, Object>();
                m.put("runId", flowRunPrcs.getRunId());
                FlowRun flowRun = wfeFlowRunMapper.find(m);
                String userName = usersService.getUserNameById(flowRun.getBeginUser());
                flowRun.setUserName(userName);
                flowRunPrcs.setFlowRun(flowRun);
            }
            toJson.setObj(list);
            toJson.setFlag(0);
            toJson.setMsg("ok");
        } else {
            toJson.setFlag(1);
            toJson.setMsg("您没有委托的工作！");
        }
        toJson.setTotleNum(pageParams.getTotal());
        return toJson;
    }

    /**
     * @创建作者:李然 Lr
     * @方法描述：收回委托
     * @创建时间：11:06 2019/5/20
     **/
    public ToJson backEntrustWork(HttpServletRequest request) {
        ToJson toJson = new ToJson(1, "err");
        try {
            String id = request.getParameter("id");
            //再次验证要收回的委托是否已经接受
            if (id != null && !id.equals("")) {
                Integer keyId = Integer.parseInt(id);
                FlowRunPrcs flowRunPrcs = wfeFlowRunPrcsMapper.selectByPrimaryKey(keyId);
                if (flowRunPrcs != null) {
                    String prcsFlag = flowRunPrcs.getPrcsFlag();
                    if (prcsFlag.equals("1")) {
                        //删除当前流程
                        wfeFlowRunPrcsMapper.deleteByPrimaryKey(keyId);
                        Map map = new HashMap();
                        map.put("runId", flowRunPrcs.getRunId());
                        map.put("prcsId", flowRunPrcs.getPrcsId());
                        map.put("prcsFlag", "2");
                        map.put("userId", flowRunPrcs.getOtherUser());
                        map.put("flowPrcs", flowRunPrcs.getFlowPrcs());
                        map.put("opFlag", "1");
                        wfeFlowRunPrcsMapper.updatePrcsFlag(map);
                        toJson.setFlag(0);
                        toJson.setMsg("ok");
                    } else {
                        //被委托人已接收
                        toJson.setMsg("被委托人已接收");
                    }
                } else {
                    //已不存在
                    toJson.setMsg("此流程不存在，可能已被删除");
                }
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        return toJson;
    }

    /**
     * @创建作者:李然 Lr
     * @方法描述：获取当前父流程或子流程
     * @创建时间：9:54 2019/6/13
     **/
    public ToJson prentAndSonFlow(HttpServletRequest request) {
        ToJson json = new ToJson(1, "err");
        final String runId = request.getParameter("runId");
        ExecutorService pool = Executors.newFixedThreadPool(2);
        Callable callableSon = new Callable() {
            @Override
            public Object call() throws Exception {
                FlowRunMapper flowRunMapper = (FlowRunMapper) SpringTool.getBean("flowRunMapper");
                Map<String, Object> map = new HashMap();
                map.put("runId", runId);
                List<FlowRun> sonFlowRunList = flowRunMapper.getSonFlowRunWork(map);
                return sonFlowRunList;
            }
        };
        Callable callablePrent = new Callable() {
            @Override
            public Object call() throws Exception {
                FlowRun flowRun1 = wfeFlowRun.find(Integer.parseInt(runId));

                Integer parentRunId = flowRun1.getParentRun();
                FlowRun flowRun2 = null;
                if (parentRunId != null && parentRunId != 0) {
                    flowRun2 = wfeFlowRun.find(parentRunId);
                }
                return flowRun2;
            }
        };
        Future<List<FlowRun>> sonFlowRun = pool.submit(callableSon);
        Future<FlowRun> parentFlowRun = pool.submit(callablePrent);

        try {
            List<FlowRun> sonO = sonFlowRun.get();
            FlowRun parentO = parentFlowRun.get();
            json.setObj(sonO);
            json.setObject(parentO);
            json.setFlag(0);
            json.setMsg("ok");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } finally {
            pool.shutdown();
        }


        return json;
    }

    /**
     * @创建作者:李然 Lr
     * @方法描述：返回父流程设置子流程步骤的人员
     * @创建时间：10:13 2019/6/19
     **/
    public ToJson returnPrentFlowUser(HttpServletRequest request) {
        Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
        Users user = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);
        ToJson toJson = new ToJson(1, "err");
        String runId = request.getParameter("runId");
        Map<Integer, Map<String, Object>> reMap = new HashMap<Integer, Map<String, Object>>();
        if (runId != null && !runId.equals("")) {
            Map map = new HashMap();
            map.put("childRun", runId);
            FlowRunPrcs flowRunPrcs = flowRunPrcsMapper.selectParentFlowRunPrcs(map);
            //根据流水号获取流程信息
            List<FlowRunPrcs> allFrp = this.findByRunId(map);
            Department dep = departmentService.getDeptById(user.getDeptId());
            if (flowRunPrcs != null) {
                //父流程设计步骤
                Integer flowPrcs = flowRunPrcs.getFlowPrcs();
                Map runMap = new HashMap();
                runMap.put("runId", flowRunPrcs.getRunId());
                FlowRun flowRun = wfeFlowRunMapper.find(runMap);
                //父流程流程id
                Integer flowId = flowRun.getFlowId();
                //根据flowId和flowPrcs查找步骤信息
                FlowProcess flowProcess = wfeFlowProcess.findbyprcsId(flowId, flowPrcs);
                if (flowProcess != null) {
                    toJson.setFlag(0);
                    if (flowProcess.getPrcsTo() != null && !flowProcess.getPrcsTo().equals("") && !flowProcess.getPrcsTo().equals("0")) {
                        if (flowProcess.getAutoUserOpReturn() != null && !flowProcess.getAutoUserOpReturn().equals("")) {
                            flowProcess.setAutoUserOpReturnName(usersService.getUserNameById(flowProcess.getAutoUserOpReturn()));
                        }
                        if (flowProcess.getAutoUserReturn() != null && !flowProcess.getAutoUserReturn().equals("")) {
                            String[] autoUserReturnArray = flowProcess.getAutoUserReturn().split(",");
                            String autoUserReturnName = "";
                            String prcsDeptName = "";
                            String prcsPrivName = "";
                            Users u = null;
                            for (String userId : autoUserReturnArray) {
                                u = usersService.getUsersByuserId(userId);
                                String userName = u.getUserName();
                                if (userName != null) {
                                    autoUserReturnName += userName + ",";
                                }
                                if (!StringUtils.checkNull(u.getDeptName())) {
                                    prcsDeptName += u.getDeptName() + ",";
                                }
                                if (!StringUtils.checkNull(u.getUserPrivName())) {
                                    prcsPrivName += u.getUserPrivName() + ",";
                                }
                            }

                            flowProcess.setAutoUserReturnName(autoUserReturnName);
                            flowProcess.setPrcsDeptName(prcsDeptName);
                            flowProcess.setPrcsUserPrivName(prcsPrivName);
                        }
                        List<Users> autoTypelist = new ArrayList<Users>();
                        Map<String, Object> temp = null;
                        try {
                            FlowProcess flowProcessTo = wfeFlowProcess.findbyprcsId(flowId, Integer.parseInt((flowProcess.getPrcsTo().split(","))[0]));
                            flowProcessTo.setAutoUserReturnName(flowProcess.getAutoUserReturnName());
                            flowProcessTo.setAutoUserReturn(flowProcess.getAutoUserReturn());
                            flowProcessTo.setAutoUserOpReturnName(flowProcess.getAutoUserOpReturnName());
                            flowProcessTo.setAutoUserOpReturn(flowProcess.getAutoUserOpReturn());
                            flowProcessTo.setPrcsDeptName(flowProcess.getPrcsDeptName());
                            flowProcessTo.setPrcsUserPrivName(flowProcess.getPrcsUserPrivName());
                            Map<String,Object> runIdMap=new HashMap();
                            runIdMap.put("runId", flowRun.getRunId());
                            List<FlowRunPrcs> allFrp2 = this.findByRunId(runIdMap);
                            //返回父流程步骤的智能选人
                            temp = wfeFlowRunInfo.reTemp(flowProcessTo, dep, user, flowRun.getRunId(), allFrp2);
                            if(flowProcessTo.getPrcsId()!=0){
                                flowProcessTo.setChildRunData(temp);
                            }
                            toJson.setObject(flowProcessTo);
                            toJson.setMsg("ok");
                        } catch (NumberFormatException e) {
                            toJson.setMsg("返回的父流程步骤中子流程结束返回步骤已经改变");
                        }
                    }
                } else {
                    toJson.setMsg("父流程步骤以不存在");
                }

            } else {
                toJson.setMsg("没有此流程的父流程");
            }
        } else {
            toJson.setMsg("参数为null");
        }
        return toJson;
    }

    //判断是否为超时工作并转交
    public void selectTimeOuts(){
        try {
           SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date dates = new Date(System.currentTimeMillis());
            long nd = 1000 * 24 * 60 * 60;//每天毫秒数
            long nh = 1000 * 60 * 60;//每小时毫秒数
            long nm = 1000 * 60;//每分钟毫秒数
            long ns = 1000;// 一秒钟的毫秒数
            List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectAllTime();
            for (FlowRunPrcs flowRunPrcs : list) {
                Integer timeOutType = flowRunPrcs.getTimeOutType();//超时计算方式
                Integer prcsId = flowRunPrcs.getPrcsId();
                Integer runId = flowRunPrcs.getRunId();
                if (flowRunPrcs.getTimeOut() != null || !"".equals(flowRunPrcs.getTimeOut().trim())) {
                    String[] timeOutShuzu = flowRunPrcs.getTimeOut().split(",");
                    double timeOut = Double.parseDouble(timeOutShuzu[0]);
                    if (timeOutShuzu[1].endsWith("hour")) {
                        timeOut = timeOut;
                    } else if (timeOutShuzu[1].endsWith("day")) {
                        timeOut = timeOut * 24;
                    }
                    Date PrcsTime = new Date();
                    Date DeliverTime = new Date();
                    long diff = 0;
                    if (timeOutType == 0) {//超时计算从此步骤接收开始
                        PrcsTime = formatter.parse(flowRunPrcs.getPrcsTime());
                        if (flowRunPrcs.getPrcsFlag().endsWith("4") || flowRunPrcs.getPrcsFlag().endsWith("3")) {
                            if (flowRunPrcs.getDeliverTime() != null && flowRunPrcs.getDeliverTime() != "") {
                                if (PrcsTime.getTime() == (-621701856000l)) {//判断工作接收时间，默认是-621701856000l
                                    continue;
                                } else {
                                    diff = formatter.parse(flowRunPrcs.getDeliverTime()).getTime() - PrcsTime.getTime();
                                }
                            }
                        } else {
                            if (flowRunPrcs.getPrcsFlag().endsWith("1")) {
                                continue;
                            }
                            diff = dates.getTime() - PrcsTime.getTime(); // 获得两个时间的毫秒时间差异
                        }
                    } else if (timeOutType == 1) {//超时计算从上一步骤转交开始
                        if (flowRunPrcs.getPrcsId() > 1) {//判断是否为第一步骤
                            if (flowRunPrcs.getPrcsFlag().endsWith("4")) {//判断是否为已办结的工作
                                diff = formatter.parse(flowRunPrcs.getPrcsTime()).getTime() - formatter.parse(flowRunPrcs.getCreateTime()).getTime();
                            } else {
                                diff = dates.getTime() - formatter.parse(flowRunPrcs.getCreateTime()).getTime();
                            }
                        } else {//如果为第一步骤，超时计算从创建工作开始
                            if (flowRunPrcs.getPrcsFlag().endsWith("4")) {
                                diff = formatter.parse(flowRunPrcs.getDeliverTime()).getTime() - formatter.parse(flowRunPrcs.getPrcsTime()).getTime();
                            } else {
                                diff = dates.getTime() - formatter.parse(flowRunPrcs.getCreateTime()).getTime();
                            }
                        }
                    }
                    boolean bol = false;
                    SysPara myproject = sysParaMapper.querySysPara("MYPROJECT");
                    if(myproject != null && !StringUtils.checkNull(myproject.getParaValue())
                            && "dazu".equals(myproject.getParaValue())){
                        bol=true;
                    }
                    long day = diff / nd;   // 计算差多少天
                    long hour = diff % nd / nh; // 计算差多少小时
                    long min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟
                    long sec = diff % nd % nh % nm / ns;// 计算差多少
                    if (diff / ns > timeOut * 60 * 60) {//如果为超时工作则将状态值改为已超时
                        //转交当前的流程
                        FlowProcess process = flowProcessMapper.findProcess(flowRunPrcs.getFlowId(), flowRunPrcs.getFlowPrcs());
                        if (process.getTimeAutoTurn().endsWith("1") && !flowRunPrcs.getPrcsFlag().endsWith("4") && !flowRunPrcs.getPrcsFlag().endsWith("3")) {
                            FlowRun flowRun = wfeFlowRunMapper.selectBuRunId(flowRunPrcs.getRunId());
                            DocumentModel documentModel = documentSerivce.checkRunId(flowRun.getRunId());
                            String tableName = "";
                            String tabId = "";
                            String smsContent = bol ? "" : "您有新的工作需要办理" + "，流水号：" + flowRun.getRunId() + "，工作名称/文号：" + flowRun.getRunName();
                            if (documentModel != null) {
                                tableName = documentModel.getTitle();
                                tabId = Integer.toString(documentModel.getId());
                            }
                            //获取下一步骤的经办人
                            FlowProcess process2 = new FlowProcess();
                            if (process.getPrcsTo().split(",").length > 1) {//自动转交下一步有多条，，无法自动转交。记录日志

                            } else if (process.getPrcsTo().split(",").length == 1) {//跳转下一步为单节点
                                process2 = flowProcessMapper.findProcess(flowRunPrcs.getFlowId(), Integer.parseInt(process.getPrcsTo().split(",")[0]));
                                Users usersByuserId = usersService.getUsersByuserId(flowRunPrcs.getUserId());
                                //获取智能选人数据
                                AjaxJson branch = wfeFlowRunInfo.getBranch(flowRun.getFlowId(), flowRunPrcs.getFlowPrcs(), flowRun.getRunId(), usersByuserId);
                                Map<Integer, Map<String, Object>> obj = (Map<Integer, Map<String, Object>>) branch.getObj();
                                Map<String, Object> step = obj.get(process.getPrcsTo().split(","));
                                List<Users> autoTypelist = (List<Users>) step.get("autoTypelist");
                                if (autoTypelist.size() > 1) {//智能选人不止一个，无法自动转交。记录日志

                                } else if (autoTypelist.size() == 0) {//智能选人为空，无法自动转交。记录日志

                                } else {
                                    workController.saveworks(flowRunPrcs.getRunId(), flowRun.getRunName(),
                                            flowRunPrcs.getFlowId(), flowRunPrcs.getPrcsId(), flowRunPrcs.getPrcsFlag(),
                                            process.getPrcsTo(), DateFormatUtils.formatDate(new Date()), process2.getPrcsUser(), process2.getPrcsUser()
                                            , process.getPrcsId(), "",
                                            ",", smsContent, "1,3,", tableName, tabId, Integer.toString(flowRunPrcs.getPrcsId()), flowRunPrcs.getUserId(), "0,");

                                }
                            } else {//下一步节点为空节点,无法自动转交。记录日志
                            }
                        }
                       /* flowRunPrcs.setTimeOutFlag("1");
                        wfeFlowRunPrcsMapper.upTimeOutFlagById(flowRunPrcs);*/
                    } else {
                        /*flowRunPrcs.setTimeOutFlag("0");
                        wfeFlowRunPrcsMapper.upTimeOutFlagById(flowRunPrcs);*/
                    }

                }
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    /**
     * @接口说明: 挂起和取消挂起
     * @日期: 2020/4/24
     * @作者: 张航宁
     */
    public ToJson<FlowRunPrcs> pendingWork(HttpServletRequest request,Integer runId,
                                           Integer id,String flowPrcs,String currentPrcsId,String flowId, String prcsId,String prcsFlag){

        ToJson<FlowRunPrcs> json = new ToJson<>();
        Map<String, Object> map = new HashMap<String, Object>();

        Cookie redisSessionCookie = CookiesUtil.getCookieByName(request, "redisSessionId");
        Users user = SessionUtils.getSessionInfo(request.getSession(), Users.class, new Users(), redisSessionCookie);

        map.put("runId", runId);
        map.put("prcsId", prcsId);
        map.put("prcsFlag", prcsFlag);
        map.put("userId", user.getUserId());
        map.put("flowPrcs", flowPrcs);
        map.put("id",id);
        int count = wfeFlowRunPrcsMapper.updateHandle(map);

        if(count>0){
            json.setFlag(0);
            json.setMsg("ok");
        }

        return json;
    }
    //查询含有办理时限的数据
    public List<FlowRunPrcs> selectAllTime(){
        return wfeFlowRunPrcsMapper.selectAllTime();
    }
    //更改超时状态值
    public int upTimeOutFlagById(FlowRunPrcs flowRunPrcs){
        return wfeFlowRunPrcsMapper.upTimeOutFlagById(flowRunPrcs);
    }

    //子流程退回到父流程
    public ToJson returnParentFrp(FlowRunPrcs flowRunPrcs) {
        ToJson json = new ToJson();
        try {
            Map<String, Object> parentMap = new HashMap<>();
            parentMap.put("childRun", flowRunPrcs.getRunId());
            FlowRun flowRun = wfeFlowRunMapper.selectBuRunId(flowRunPrcs.getRunId());//子流程的flowRun
            FlowRunPrcs parentFrp = flowRunPrcsMapper.selectParentFlowRunPrcs(parentMap);//父流程frp
            if (parentFrp != null) {//判断父流程对应的节点是否已经被删除
                FlowRunLog flowRunLog = wfeLog.getFlowRunLogByRequest(request);//日志
                flowRunLog.setRunId(flowRunPrcs.getRunId());
                Map<String, Object> map = new HashMap<>();
                map.put("delFlag", 1);
                map.put("runId", flowRunPrcs.getRunId());
                map.put("delTime", DateFormat.getStrDate(new Date()));
                wfeFlowRun.updateState(map);
                Map<String, String> smsMap = new HashMap<>();
                smsMap.put("prcsId", String.valueOf(flowRunPrcs.getPrcsId()));
                smsMap.put("flowId", String.valueOf(flowRun.getFlowId()));
                smsService.querySmsByTypeUpdateRunId("7", String.valueOf(flowRunPrcs.getRunId()), smsMap);
                //插入日志
                flowRunLog.setType(Constant.TYPE10);
                //获取流程节点上一步骤
                Map<String, Object> map1 = new HashMap<>();
                map1.put("prcsId", parentFrp.getParentPrcsId());
                map1.put("flowPrcs", parentFrp.getParent());
                map1.put("runId", parentFrp.getRunId());
                List<FlowRunPrcs> list = this.findByRunId(map1);
                list.get(0).setPrcsFlag("2");
                list.get(0).setDeliverTime("2000-01-01 00:00:00");
                this.updateFrpById(list.get(0));
                //更新转交子流程的人员为待办
                wfeFlowRunPrcsMapper.deleteByPrimaryKey(parentFrp.getId());//将父流程的转子节点的步骤删除
                wfeLog.addFlowRunLog(flowRunLog);//添加日志
                json.setFlag(0);
                json.setMsg("退回成功");
            } else {//父流程对应的节点被删除，将子流程删除
                Map<String, Object> map = new HashMap<>();
                map.put("delFlag", 1);
                map.put("runId", flowRunPrcs.getRunId());
                map.put("delTime", DateFormat.getStrDate(new Date()));
                wfeFlowRun.updateState(map);
                json.setFlag(0);
                json.setMsg("无父流程，将子流程状态改为删除");
            }
        } catch (Exception e) {
            json.setFlag(1);
            json.setMsg("异常");
        }
        return json;
    }

    public  FlowRunPrcs selectByPrimaryKey(Integer id){
        return wfeFlowRunPrcsMapper.selectByPrimaryKey(id);
    }

    public ToJson getAssignData(Map<String, Object> maps, Integer page,
                                Integer pageSize, boolean useFlag) {
        ToJson toJson = new ToJson();
        List<FlowRunPrcs> list = wfeFlowRunPrcsMapper.selectObjcet(maps);
        //增加经办人的待办数据
        List<FlowRunPrcs> assignFrp = new ArrayList<FlowRunPrcs>();
        List<FlowRunPrcs> commonData = new ArrayList<FlowRunPrcs>();
        if (list.size() > 0) {
            for (FlowRunPrcs flowRunPrcs : list) {
                flowRunPrcs.getFlowRun().setUserName(usersService.getUserNameById(flowRunPrcs.getFlowRun().getBeginUser()));
                Map<String, Object> map = new HashMap();
                map.put("runId", flowRunPrcs.getRunId());
                map.put("prcsId", flowRunPrcs.getPrcsId());
                map.put("flowPrcs", flowRunPrcs.getFlowPrcs());
                map.put("userId", maps.get("userId"));
                Boolean isAssignData = false;
                //获取所有增加经办人数据
                List<FlowRunPrcs> frps = wfeFlowRunPrcsMapper.getAssignData(map);
                StringBuffer onWork = new StringBuffer();
                StringBuffer endWork = new StringBuffer();
                StringBuffer fawonWork = new StringBuffer();
                StringBuffer fawendWork = new StringBuffer();
                Boolean isFawData = false;
                if (frps.size() > 0) {//含有增加经办人
                    for (FlowRunPrcs frp : frps) {
                        if (frp.getOpaddUser().equals(flowRunPrcs.getUserId())&&frp.getFlowPrcs().equals(flowRunPrcs.getFlowPrcs())) {
                            if(Integer.parseInt(frp.getPrcsFlag()) < 3){
                                onWork.append(frp.getUserId() + ",");
                                isAssignData = true;
                            }else{
                                endWork.append(frp.getUserId() + ",");
                            }
                        }
                        if (!StringUtils.checkNull(frp.getComment()) && frp.getComment().equals("1")) {
                            flowRunPrcs.setComment(String.valueOf(frp.getId()));
                        }
                    }
                    List<FlowAssignWithBLOBs> assign = flowAssignMapper.getAssigns(flowRunPrcs.getRunId(), flowRunPrcs.getPrcsId(), String.valueOf(flowRunPrcs.getFlowPrcs()));
                    if (assign.size() > 0) {
                        for (FlowAssignWithBLOBs faw : assign) {
                            if (faw.getAssignUser().equals(flowRunPrcs.getUserId())&&faw.getFlowPrcs().equals(flowRunPrcs.getFlowPrcs())) {
                                if(faw.getHandleStatus() != 2){
                                    fawonWork.append(faw.getHandleUser() + ",");
                                    isFawData = true;
                                }else{
                                    fawendWork.append(faw.getHandleUser() + ",");
                                }
                            }
                            //获取交办表中的数据对应的frp中的数据
                            Map<String, Object> assMap = new HashMap<>();
                            assMap.put("userId", faw.getHandleUser());
                            assMap.put("flowPrcs", faw.getFlowPrcs());
                            assMap.put("prcsId", faw.getPrcsId());
                            assMap.put("runId", faw.getRunId());
                            List<FlowRunPrcs> fawFrp = wfeFlowRunPrcsMapper.selectFind(assMap);
                            if (fawFrp.size() > 0) {
                                if (!StringUtils.checkNull(fawFrp.get(0).getComment()) && fawFrp.get(0).getComment().equals("1")) {
                                    flowRunPrcs.setComment(String.valueOf(fawFrp.get(0).getId()));
                                }
                            }
                        }
                    }
                    if (isAssignData || isFawData) {//需显示在经办的数据
                        //正在办理中的增加经办人的数据
                        String onWorkUsername = null;
                        if (!StringUtils.checkNull(onWork.toString())) {
                            onWorkUsername = usersService.getUserNameById(onWork.toString());
                        }
                        //已经办结的增加经办人数据
                        String endWorkUsername = null;
                        if (!StringUtils.checkNull(endWork.toString())) {
                            endWorkUsername = usersService.getUserNameById(endWork.toString());
                        }
                        Map<String, Object> shouAssign = new HashMap<>();
                        if (onWorkUsername != null) {
                            shouAssign.put("ason", "待办经办人：" + onWorkUsername);
                        }
                        if (endWorkUsername != null) {
                            shouAssign.put("asend", "已办经办人：" + endWorkUsername);
                        }
                        if (assign.size() > 0) {
                            if (isFawData) {
                                //正在办理中的交办数据
                                String fawonWorkUsername = null;
                                if (!StringUtils.checkNull(fawonWork.toString())) {
                                    fawonWorkUsername = usersService.getUserNameById(fawonWork.toString());
                                }
                                //已经办结的交办数据
                                String fawendWorkUsername = null;
                                if (!StringUtils.checkNull(fawendWork.toString())) {
                                    fawendWorkUsername = usersService.getUserNameById(fawendWork.toString());
                                }
                                if (fawonWorkUsername != null) {
                                    shouAssign.put("faon", "待办交办人：" + fawonWorkUsername);
                                }
                                if (fawendWorkUsername != null) {
                                    shouAssign.put("faend", "已办交办人：" + fawendWorkUsername);
                                }
                            }
                            flowRunPrcs.setHandles(shouAssign);
                            assignFrp.add(flowRunPrcs);
                        } else {
                            //存放至对象中，返回前台
                            flowRunPrcs.setHandles(shouAssign);
                            assignFrp.add(flowRunPrcs);
                        }
                        continue;
                    } else {//增加经办人全部已办结，放置待办中
                        commonData.add(flowRunPrcs);
                    }
                } else {//是否含有交办人
                    List<FlowAssignWithBLOBs> assign = flowAssignMapper.getAssigns(flowRunPrcs.getRunId(), flowRunPrcs.getPrcsId(), String.valueOf(flowRunPrcs.getFlowPrcs()));
                    if (assign.size() > 0) {//有交办人
                        for (FlowAssignWithBLOBs faw : assign) {
                            if (faw.getAssignUser().equals(flowRunPrcs.getUserId())&&faw.getFlowPrcs().equals(flowRunPrcs.getFlowPrcs())) {
                                if(faw.getHandleStatus() != 2){
                                    fawonWork.append(faw.getHandleUser() + ",");
                                    isFawData = true;
                                }else{
                                    fawendWork.append(faw.getHandleUser() + ",");
                                }
                            }
                            //获取交办表中的数据对应的frp中的数据
                            Map<String, Object> assMap = new HashMap<>();
                            assMap.put("userId", faw.getHandleUser());
                            assMap.put("flowPrcs", faw.getFlowPrcs());
                            assMap.put("prcsId", faw.getPrcsId());
                            assMap.put("runId", faw.getRunId());
                            List<FlowRunPrcs> fawFrp = wfeFlowRunPrcsMapper.selectFind(assMap);
                            if (fawFrp.size() > 0) {
                                if (!StringUtils.checkNull(fawFrp.get(0).getComment()) && fawFrp.get(0).getComment().equals("1")) {
                                    flowRunPrcs.setComment(String.valueOf(fawFrp.get(0).getId()));
                                }
                            }
                        }
                        if (isFawData) {
                            //正在办理中的交办数据
                            String fawonWorkUsername = null;
                            if (!StringUtils.checkNull(fawonWork.toString())) {
                                fawonWorkUsername = usersService.getUserNameById(fawonWork.toString());
                            }
                            //已经办结的交办数据
                            String fawendWorkUsername = null;
                            if (!StringUtils.checkNull(fawendWork.toString())) {
                                fawendWorkUsername = usersService.getUserNameById(fawendWork.toString());
                            }
                            Map<String, Object> shouFaw = new HashMap<>();
                            if (fawonWorkUsername != null) {
                                shouFaw.put("faon", "待办交办人：" + fawonWorkUsername);
                            }
                            if (fawendWorkUsername != null) {
                                shouFaw.put("faend", "已办交办人：" + fawendWorkUsername);
                            }
                            flowRunPrcs.setHandles(shouFaw);
                            assignFrp.add(flowRunPrcs);
                            continue;
                        } else {//交办全部已办结，放置待办中
                            commonData.add(flowRunPrcs);
                        }
                    } else {//无交办和增加经办人数据，属于正常转交
                        commonData.add(flowRunPrcs);
                    }
                }
            }
            Map<String, Object> showMap = new HashMap();
            showMap.put("commonData", commonData);
            showMap.put("assignData", assignFrp);
            toJson.setObject(showMap);
            toJson.setFlag(0);
        } else {
            toJson.setFlag(0);
            toJson.setMsg("ok");
        }
        return toJson;
    }
    //批量下载附件为zip文件
    public ToJson downLoadZipAtt(HttpServletRequest request, HttpServletResponse response) {
        String flowName = request.getParameter("flowName");
        List<Attachment> allAttachmentList = new ArrayList<>();
        String company = "xoa" + (String) request.getSession().getAttribute(
                "loginDateSouse");
        //读取配置文件
        ResourceBundle rb = ResourceBundle.getBundle("upload");
        String osName = System.getProperty("os.name");
        StringBuffer sbf = new StringBuffer();
        if (osName.toLowerCase().startsWith("win")) {
            //判断路径是否是相对路径，如果是的话，加上运行的路径
            String uploadPath = rb.getString("upload.win");
            if (uploadPath.indexOf(":") == -1) {
                //获取运行时的路径
                String basePath = this.getClass().getClassLoader().getResource(".").getPath() + File.pathSeparator;
                //获取截取后的路径
                String str2 = "";
                if (basePath.indexOf("/xoa") != -1) {
                    //获取字符串的长度
                    int length = basePath.length();
                    //返回指定字符在此字符串中第一次出现处的索引
                    int index = basePath.indexOf("/xoa");
                    //从指定位置开始到指定位置结束截取字符串
                    str2 = basePath.substring(0, index);
                }
                sbf = sbf.append(str2 + "/xoa");
            }
            sbf.append(uploadPath);
        } else {
            sbf = sbf.append(rb.getString("upload.linux"));
        }
        String attachments = request.getParameter("attachments");//需要下载的文件
        JSONArray json = new JSONArray();
        List attachmentList = json.parseObject(attachments, List.class);
        for (Object att : attachmentList) {
            Map map = json.parseObject(String.valueOf(att), Map.class);
            String attachName = String.valueOf(map.get("attachName"));
            String attachId = String.valueOf(map.get("attachId"));
            String module = String.valueOf(map.get("module"));
            List<Attachment> atts = GetAttachmentListUtil.returnAttachment(attachName,attachId ,company,module );
            if (String.valueOf(map.get("module")).equals("document")) {
                atts.get(0).setModule((byte) 1);
            } else if (String.valueOf(map.get("module")).equals("workflow")) {
                atts.get(0).setModule((byte) 2);
            }
            atts.get(0).setType(String.valueOf(map.get("type")));
            allAttachmentList.addAll(atts);
        }
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());) {
            String zipNameOut = URLEncoder.encode(flowName, "UTF-8") + ".zip";
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=\"%s\"", zipNameOut));
            String zipName = File.separator;// 定义压缩包名称 用户名-部门名称
            if (attachmentList != null && attachmentList.size() > 0) {
                for (int i=0;i<allAttachmentList.size();i++) {
                    Attachment attachment = allAttachmentList.get(i);
                    String module = "";
                    if (String.valueOf(attachment.getModule()).equals("1")) {
                        module = "document";
                    } else if (String.valueOf(attachment.getModule()).equals("2")) {
                        module = "workflow";
                    }
                    String ym = attachment.getYm();
                    String attachmentId = attachment.getAttachId();
                    String attachmentName = attachment.getAttachName();

                    //---------------------------------判断是否为Linux开始-------------------------------------

                    try {
                        int codeLength = attachmentName.getBytes("UTF-8").length;
                        String type = attachmentName.substring(attachmentName.lastIndexOf("."));
                        if(codeLength>230&&osName.toLowerCase().startsWith("linu")){//判断
                            String s = (new BASE64Encoder()).encodeBuffer((attachmentName.substring(0,attachmentName.lastIndexOf("."))).getBytes(StandardCharsets.UTF_8));
                            String regEx=("[\\s\\\\/:\\*\\?\\\"<>\\|]");
                            attachmentName=(Pattern.compile(regEx).matcher(s).replaceAll("").trim().substring(0,100))+type;
                        }
                    }catch (Exception e){

                    }

                    //---------------------------------判断是否为Linux结束-------------------------------------

                    StringBuilder sb = new StringBuilder(sbf);
                    if (StringUtils.checkNull(sb.toString())) {
                        String a = request.getRealPath("");
                        sb.append(a);
                        sb.append(System.getProperty("file.separator")).
                                append(company).append(System.getProperty("file.separator")).
                                append(module).append(System.getProperty("file.separator")).append(ym).
                                append(System.getProperty("file.separator")).append(attachmentId).append(".").append(attachmentName);
                    } else {
                        sb.append(System.getProperty("file.separator")).
                                append(company).append(System.getProperty("file.separator")).
                                append(module).append(System.getProperty("file.separator")).append(ym).
                                append(System.getProperty("file.separator")).append(attachmentId).append(".").append(attachmentName);
                    }

                    String path = sb.toString();
                    //是否是加密文件
                    boolean bol = false;
                    File file = new File(path);
                    if (!file.exists()) {
                        file = new File(path + ".xoafile");
                        bol = true;
                    }
                    if (file.exists()) {
                        ZipEntry ze =null;
                        if(attachment.getType().equals("1")){//公共附件
                            ze=new ZipEntry(zipName + ("公共附件"+(i+1)+"_")+attachment.getAttachName());
                        }else if(attachment.getType().equals("2")){//表单附件
                            ze=new ZipEntry(zipName + ("表单附件"+(i+1)+"_")+attachment.getAttachName());
                        } else if(attachment.getType().equals("3")){//原始正文
                            ze=new ZipEntry(zipName + ("(原始正文)")+attachment.getAttachName());
                        }else if(attachment.getType().equals("4")){//修订正文
                            ze=new ZipEntry(zipName + ("(留痕正文)")+attachment.getAttachName());
                        }else if(attachment.getType().equals("5")){//定稿正文
                            ze=new ZipEntry(zipName + ("(定稿正文)")+attachment.getAttachName());
                        }else if(attachment.getType().equals("6")){//版式正文
                            ze=new ZipEntry(zipName + ("(转版正文)")+attachment.getAttachName());
                        }
//                        ZipEntry ze = new ZipEntry(zipName + attachmentName);
                        zipOutputStream.putNextEntry(ze);
                        byte[] abc = AESUtil.download(file, company, bol);
                        zipOutputStream.write(abc, 0, abc.length);
                        zipOutputStream.flush();
                    }
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public List<FlowRunPrcs> getfrpByrollBack(Map<String, Object> maps){
        return wfeFlowRunPrcsMapper.getfrpByrollBack(maps);
    }
    public String getUserIdByMaxFlowPrcs(Integer flowPrcs, Integer runId){
        return wfeFlowRunPrcsMapper.getUserIdByMaxFlowPrcs(flowPrcs,runId);
    };
}